package com.campuscrowdsourcing.server.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.campuscrowdsourcing.server.common.expection.ServiceException;
import com.campuscrowdsourcing.server.domain.entity.SystemFile;
import com.campuscrowdsourcing.server.domain.vo.FileVO;
import com.campuscrowdsourcing.server.mapper.SystemFileMapper;
import com.campuscrowdsourcing.server.service.SystemFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.campuscrowdsourcing.server.utils.CommonFileUtil;
import nl.basjes.shaded.org.springframework.util.ResourceUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.system.ApplicationHome;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDateTime;

/**
 * <p>
 * 文件信息表 服务实现类
 * </p>
 *
 * @author Xinyuan Zhao
 * @since 2023-03-20
 */
@Service
public class SystemFileServiceImpl extends ServiceImpl<SystemFileMapper, SystemFile> implements SystemFileService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());


    public final  String commonUrl = "localhost:9000";


    /**
     * 上传图片文件
     * @param file 文件
     * @param userId 业务ID
     * @return 文件ID
     */
    @Override
    public FileVO uploadImageFile(MultipartFile file, Integer userId){
        if(file == null){
            throw new ServiceException("请上传图片");
        }
        //文件类型
        String fileType = CommonFileUtil.getType(file);
        if(StrUtil.isBlank(fileType)){
            throw new ServiceException("请选择规定文件上传");
        }
        //文件原始昵称
        String originalFilename = file.getOriginalFilename();
        //后缀名
        String extName = FileUtil.extName(originalFilename);
        //文件大小
        long size = file.getSize();
        if((size/(1024*1024)) > 5 ){
            throw new ServiceException("文件过大");
        }

        //上传文件
        SystemFile systemFile = new SystemFile();
        FileVO fileVO = new FileVO();
        //如果文件存在直接返回文件信息
        String mD5 = null;
        try{
            mD5 = CommonFileUtil.compMd5(file);
            systemFile = getOne(new QueryWrapper<SystemFile>().eq("md5",mD5));
            if(systemFile != null){
                fileVO.setUrl(systemFile.getUrl());
                fileVO.setId(systemFile.getId());
                return fileVO;
            }else{
                systemFile = new SystemFile();
            }
        }catch (Exception e){
            logger.error(String.valueOf(e));
        }
        // 定义一个文件唯一的uuid昵称
        String fileName =  IdUtil.fastSimpleUUID() + StrUtil.DOT + fileType;
        // 判断配置的文件目录是否存在，若不存在则创建一个新的文件目录
        String path = getSavePath();
        File files = new File(path, fileName);
        File parentFile = new File(path);
        if (!parentFile.isDirectory()) {
            parentFile.mkdirs();
        }

        //构建真实的文件路径
        if(Boolean.FALSE.equals(saveFile(file, files))){
            throw new ServiceException("上传失败");
        }

        //访问链接
        String url = "http://" + commonUrl + "/image/" +  fileName;

        systemFile.setCreateTime(LocalDateTime.now());
        systemFile.setFileType("Image");
        systemFile.setUserId(userId);
        systemFile.setSize(String.valueOf(size));
        systemFile.setSubmitName(originalFilename);
        systemFile.setStatus(true);
        systemFile.setExtension(extName);
        systemFile.setMd5(mD5);
        systemFile.setName(fileName);
        systemFile.setUrl(url);
        systemFile.setRelativePath(url);
        systemFile.setIsDeleted(false);
        try{
            save(systemFile);
        }catch (Exception e){
            throw new ServiceException("上传失败");
        }

        fileVO.setId(systemFile.getId());
        fileVO.setUrl(url);
        return fileVO;
    }

    /**
     * 写入文件
     * @param file 文件
     * @return Boolean
     */
    private Boolean saveFile(MultipartFile file, File saveFile){
        try {
            // 上传文件到磁盘
            file.transferTo(saveFile);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            logger.error(String.valueOf(e));
            return false;
        }
    }


    public String getSavePath() {
        // 这里需要注意的是ApplicationHome是属于SpringBoot的类
        // 获取项目下resources/static/img路径
        ApplicationHome applicationHome = new ApplicationHome(this.getClass());

        // 保存目录位置根据项目需求可随意更改
        return applicationHome.getDir().getParentFile()
                .getParentFile().getAbsolutePath() + "\\src\\main\\resources\\static\\img";
    }
}
